package net.towee.client.xmpp;

import net.towee.client.siowrapper.SocketIOClient;
import net.towee.client.siowrapper.event.SIOConnectedEvent;
import net.towee.client.siowrapper.event.SIOConnectedEvent.SIOConnectedHandler;
import net.towee.client.siowrapper.event.SIODisconnectEvent;
import net.towee.client.siowrapper.event.SIODisconnectEvent.SIODisconnectHandler;
import net.towee.client.siowrapper.event.SIOMessageEvent;
import net.towee.client.siowrapper.event.SIOMessageEvent.SIOMessageHandler;
import net.towee.client.siowrapper.event.SIOReconnectedEvent;
import net.towee.client.siowrapper.event.SIOReconnectedEvent.SIOReconnectedHandler;
import net.towee.server.sio.common.ConnectionState;

import com.calclab.emite.core.client.bosh.StreamSettings;
import com.calclab.emite.core.client.conn.XmppConnectionBoilerPlate;
import com.calclab.emite.core.client.events.EmiteEventBus;
import com.calclab.emite.core.client.packet.IPacket;
import com.calclab.emite.core.client.services.gwt.GWTXMLService;
import com.google.inject.Inject;
import com.google.inject.Singleton;

@Singleton
public class ToweeXmppConnection extends XmppConnectionBoilerPlate implements SIOConnectedHandler, SIOReconnectedHandler, SIOMessageHandler, SIODisconnectHandler  {

	@Inject
	public ToweeXmppConnection(EmiteEventBus eventBus) {
		super(eventBus);
		
		SocketIOClient.getInstance().addSIOConnectedHandler(this);
		SocketIOClient.getInstance().addSIOReconnectedHandler(this);
		SocketIOClient.getInstance().addSIOMessageHandler(this);
		SocketIOClient.getInstance().addSIODisconnectHandler(this);
	}
	
	@Override
	public void connect() {
		setActive(true);
		fireConnected();
	}

	@Override
	public void disconnect() {
		setActive(false);
		fireDisconnected("logged out");
	}

	@Override
	public boolean isConnected() {
		return SocketIOClient.getInstance().getConnectionState().equals( ConnectionState.CONNECTED ) && isActive();
	}

	@Override
	public void send(IPacket packet) {
		if(isActive()) 
			SocketIOClient.getInstance().sendMessage("2" + GWTXMLService.toString(packet));
		else
			fireError("Can't send message because havn't connection");
	}
	
	/**
	 * Invoked when connection est.
	 */
	public void onConnected() {
		setActive(true);
	}
	
	@Override
	public void onSIOMessage(SIOMessageEvent event) {
		// Get response type
		int respType = Integer.parseInt(event.getMessage().substring(0, 1));

		// It's a request/response pattern
		if (respType == 2) {
			// Parse response
			IPacket response = GWTXMLService.toXML( event.getMessage().substring(1) );
		
			// Fire event
			fireStanzaReceived( response );
		}
	}
	
	@Override
	public void onSIOReconnected(SIOReconnectedEvent event) {
		this.onConnected();
	}

	@Override
	public void onSIOConnected(SIOConnectedEvent event) {
		this.onConnected();
	}
	
	@Override
	public void onSIODisconnect(SIODisconnectEvent event) {
		fireDisconnected("Connection lost");
	}

	/*
	 * Not needed methods
	 */
	@Override
	public StreamSettings pause() {
		return null;
	}

	@Override
	public void restartStream() {
	}

	@Override
	public boolean resume(StreamSettings settings) {
		return false;
	}
}
